{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "source": [
    "# 8 高级特性（一）：类和对象"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "## 1.创建一个类 People"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "1. 包含属性 `name`, `city`\n",
    "\n",
    "2. 可以转换为字符串形式 (`__str__`)\n",
    "\n",
    "3. 包含方法 `moveto(self, newcity)`\n",
    "\n",
    "4. 可以按照 `city` 排序\n",
    "\n",
    "5. 创建 4 个人对象，放到列表进行排序"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "class People:\n",
    "\n",
    "    # 1. 属性 name 和 city\n",
    "    def __init__(self, name, city):\n",
    "        self.name = name\n",
    "        self.city = city\n",
    "    \n",
    "    # 2. 转换为字符串形式，使用特殊方法 __str__\n",
    "    def __str__(self):\n",
    "        return \"<%s: %s>\" % (self.name, self.city)\n",
    "\n",
    "    # 3. 方法 moveto\n",
    "    def moveto(self, newcity):\n",
    "        self.city = newcity\n",
    "    \n",
    "    # 4. 按照 city 排序\n",
    "    def __lt__(self, other):\n",
    "        return self.city < other.city\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "<Mark: Shanghai> <Tom: Beijing> <Jack: Nanjing> <Scott: Tianjin>\n<Tom: Guangzhou>\n['<Tom: Guangzhou>', '<Jack: Nanjing>', '<Mark: Shanghai>', '<Scott: Tianjin>']\n"
     ]
    }
   ],
   "source": [
    "# 创建 4 个人对象进行测试\n",
    "a = People(\"Mark\", \"Shanghai\")\n",
    "b = People(\"Tom\", \"Beijing\")\n",
    "c = People(\"Jack\", \"Nanjing\")\n",
    "d = People(\"Scott\", \"Tianjin\")\n",
    "\n",
    "# 转字符串\n",
    "print(a, b, c, d)  \n",
    "\n",
    "# b移居新城市\n",
    "b.moveto(\"Guangzhou\")\n",
    "print(b)\n",
    "\n",
    "# 按照 city 排序\n",
    "s = [a, b, c, d]\n",
    "s.sort()\n",
    "print(list(map(str, s)))\n",
    "# print(s)  # 为啥只打印内存地址？"
   ]
  },
  {
   "source": [
    "## 2.创建一个类 Teacher"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "1. 是 `People` 子类，新增属性 `school`\n",
    "\n",
    "2. `moveto` 方法改为 `newschool`\n",
    "\n",
    "3. 按照 `school` 排序\n",
    "\n",
    "4. 创建 4 个教师对象，放到列表进行排序"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "class Teacher(People):\n",
    "    \n",
    "    # 新增属性 school\n",
    "    def __init__(self, name, city, school):\n",
    "        super().__init__(name, city)\n",
    "        self.school = school\n",
    "    \n",
    "    # moveto 方法改为 newschool\n",
    "    def moveto(self, newschool):\n",
    "        self.school = newschool\n",
    "    \n",
    "    # 按照 school 排序\n",
    "    def __lt__(self, other):\n",
    "        return self.school < other.school\n",
    "    "
   ],
   "cell_type": "code",
   "metadata": {},
   "execution_count": 33,
   "outputs": []
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "<A: Beijing> <B: Beijing> <C: Shanghai> <D: Nanjing>\n<C: Shanghai>\n['<D: Nanjing>', '<B: Beijing>', '<C: Shanghai>', '<A: Beijing>']\n"
     ]
    }
   ],
   "source": [
    "# 创建 4 个教师对象进行测试\n",
    "teacher_a = Teacher('A', 'Beijing', 'THU')\n",
    "teacher_b = Teacher('B', 'Beijing', 'PKU')\n",
    "teacher_c = Teacher('C', 'Shanghai', 'Fudan')\n",
    "teacher_d = Teacher('D', 'Nanjing', 'NJU')\n",
    "\n",
    "# 转字符串\n",
    "print(teacher_a, teacher_b, teacher_c, teacher_d)\n",
    "\n",
    "# 教师 c 跳槽至上海交通大学\n",
    "teacher_c.moveto('SJTU')\n",
    "print(teacher_c)\n",
    "\n",
    "# 按照 school 排序\n",
    "s = [teacher_a, teacher_b, teacher_c, teacher_d]\n",
    "s.sort()\n",
    "print(list(map(str, s)))"
   ]
  },
  {
   "source": [
    "## 3.创建一个 mylist 类，继承自内置数据类型 list"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "1. 增加一个“累乘” `product`\n",
    "2. `def product(def)`\n",
    "3. 返回所有数据项的乘积"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "class mylist(list):\n",
    "    \n",
    "    def product(self):\n",
    "        total = 1\n",
    "        for i in self:\n",
    "            total *= i\n",
    "        return total\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "[1, 2, 3, 4, 5]\n120\n"
     ]
    }
   ],
   "source": [
    "# 测试\n",
    "a = mylist([1, 2, 3, 4, 5])\n",
    "total = a.product()\n",
    "print(a)\n",
    "print(total)"
   ]
  }
 ]
}